<template>
  <div class="app-container">
    <el-form :model="formData" class="demo-form-inline" ref="formDom" :rules="rules" v-loading="loading">
      <el-space wrap fill style="width: 100%" size="large">
        <template v-for="(form_item, index) in form_config_item" :key="form_item.key">
          <el-card class="box-card">
            <warning-bar
              v-if="index === 0"
              title="需要先选择客户，才能加载出来环境列表。创建license前请先创建客户及其环境信息"
            />
            <div class="box-row">
              <el-row :gutter="50">
                <template v-for="item in form_item[form_item.key]" :key="item.prop">
                  <el-col :span="item.col || 24">
                    <!--                  select选择器-->
                    <el-form-item
                      v-if="item.type === 'select'"
                      :label="item.label"
                      :prop="item.prop"
                      :rules="item.rules"
                    >
                      <el-select
                        v-model="formData[item.prop]"
                        :style="`width: ${item.width}`"
                        placeholder="请选择"
                        clearable
                        filterable
                      >
                        <el-option
                          v-for="select in item.options"
                          :key="select.value"
                          :label="select.label"
                          :value="select.value"
                        ></el-option>
                      </el-select>
                    </el-form-item>

                    <!--                  时间日期选择器-->
                    <el-form-item v-if="item.type === 'date'" :label="item.label" :prop="item.prop" :rules="item.rules">
                      <el-date-picker
                        v-model="formData[item.prop]"
                        :style="`width: ${item.width}`"
                        :type="item.date_type || 'datetime'"
                        :format="item.date_format || 'YYYY-MM-DD HH:mm:ss'"
                        :value-format="item.date_value || 'YYYY-MM-DD HH:mm:ss'"
                        :placeholder="item.placeholder || '选择日期时间'"
                        :shortcuts="expireDateshortcuts"
                      ></el-date-picker>
                    </el-form-item>

                    <!--                  input输入框 -->
                    <el-form-item
                      v-if="item.type === 'input'"
                      :label="item.label"
                      :prop="item.prop"
                      :rules="item.rules"
                    >
                      <el-input
                        :maxlength="item.max_length"
                        :minlength="item.min_length"
                        :style="`width: ${item.width}`"
                        :placeholder="item.placeholder"
                        v-model.trim="formData[item.prop]"
                        clearable
                      ></el-input>
                    </el-form-item>

                    <!-- inputNumber -->
                    <el-form-item
                      v-if="item.type === 'inputNumber'"
                      :label="item.label"
                      :prop="item.prop"
                      :rules="item.rules"
                    >
                      <el-input
                        :min="item.min || 0"
                        :max="item.max || 999999999"
                        v-model.number="formData[item.prop]"
                        clearable
                      ></el-input>
                    </el-form-item>


                    <!--                  一键填入企业版组件黑名单 -->
                    <el-form-item v-if="item.type === 'button'">
                      <el-tooltip class="box-item" effect="dark" :content="item.label" placement="top-end">
                        <el-button icon="Pointer" type="primary" circle
                                   @click="setStudioCompBlackList()"
                        >
                        </el-button>
                      </el-tooltip>

                    </el-form-item>
                  </el-col>
                </template>
              </el-row>
            </div>
          </el-card>
        </template>

        <!--        权限设置-->
        <Permission
          v-if="isReadyToRender"
          :licenseVersion="formData.licenseVersion"
          :propCheckList="formData.checkList"
          @submit-permission="handlerSubmitForm"
        />
      </el-space>
    </el-form>
  </div>
</template>

<script lang="ts" setup>
import {onBeforeMount, reactive, ref, watch} from "vue"
import Permission from "../components/permissionSetting/index.vue"
import {selectOption} from "@/api/customer"
import {reqLicense, addCustomerLicenseApi, getLicenseApi, GetLicenseResponseData} from "@/api/license/license"
import {formatDate, formatDateTime} from "@/utils"
import {rulesHook} from "@/hooks/rulesHook"
import type {FormInstance} from "element-plus"
import {ElMessage} from "element-plus"
import {useRoute, useRouter} from "vue-router"
import {getAllCustomer, getCustomerEnv} from "@/utils/customer"
import WarningBar from "@/components/WarningBar/warningBar.vue"
import {expireDateshortcuts} from "@/config/dateDict";

defineOptions({
  name: "License"
})

const {InitRules} = rulesHook()
const formDom = ref<FormInstance>()
const loading = ref(false)
const isReadyToRender = ref(false);
const d = new Date()
const formData = reactive<reqLicense>({
  customerID: "",
  envID: "",
  licenseVersion: 2,
  compDisplayName: "",
  expiredDate: formatDate(d.setTime(d.getTime() + 3600 * 1000 * 24 * 31)),
  managerApis: 1000,
  managerUsers: 1000,
  managerProjects: 1000,
  managerIntegrations: 10,
  managerOrganizations: 100,
  managerTests: 100,
  managerProducts: 100,
  studioUsers: 100,
  studioCompBlackList: "",
  permissionMenu: "",
  checkList: "",
  runtimeCheckList: "",
  coreApiVersion: "",
  runtimeVersion: "",
  cfgVersion: ""
})


const router = useRouter()
const customerOptions = ref<selectOption[]>([])
const envOptions = ref<selectOption[]>([])

// 监听formData.customerID的变化，以便获取对应的环境列表
watch(
  () => formData.customerID,
  (newValue) => {
    if (!isReadyToRender.value) {
      return
    }
    // 客户id变了，需要先清空当前选择的env
    formData.envID = ""
    loading.value = true
    // 获取客户的所有环境
    getCustomerEnv(formData.customerID).then((Options) => {
      if (Options) {
        envOptions.value = Options || []
        if (envOptions.value.length === 0) {
          ElMessage({
            type: "error",
            message: "当前客户没有对应的环境信息，如需创建license，请先创建此客户的环境信息！"
          })
        }
      }
    }).finally(() => {
      loading.value = false
    })
  }
)


//#region 根据license id获取license详情
const route = useRoute();
const licenseID = route.params.id
let tempEnv: string
const getLicenseInfo = async () => {
  if (licenseID !== "0") {
    const callback = (res: GetLicenseResponseData) => {
      if (res && res.data) {
        const resData = res.data
        if (resData.list.length === 0) {
          ElMessage.error('未获取到旧license的信息')
          return
        } else {
          const license = resData.list[0]

          formData.customerID = license.customerID
          tempEnv = license.envID
          formData.licenseVersion = license.licenseVersion
          formData.compDisplayName = license.compDisplayName
          formData.managerApis = license.managerApis
          formData.managerUsers = license.managerUsers
          formData.managerProjects = license.managerProjects
          formData.managerIntegrations = license.managerIntegrations
          formData.managerOrganizations = license.managerOrganizations
          formData.managerTests = license.managerTests
          formData.managerProducts = license.managerProducts
          formData.studioUsers = license.studioUsers
          formData.studioCompBlackList = license.studioCompBlackList
          formData.permissionMenu = license.permissionMenu
          formData.checkList = license.checkList
          formData.coreApiVersion = license.coreApiVersion
          formData.runtimeVersion = license.runtimeVersion
          formData.cfgVersion = license.cfgVersion
        }
      }
    }

    // 使用 Promise 包装异步操作
    return new Promise<void>((resolve, reject) => {
      getLicenseApi({id: licenseID})
        .then(callback)
        .catch(callback)
        .finally(() => {
          resolve()
        });
    });
  }
}

// 在组件渲染之前触发接口请求
onBeforeMount(async () => {
  getAllCustomer().then((Options) => {
    if (Options) {
      customerOptions.value = Options || []
    }
  })


  await getLicenseInfo()
  isReadyToRender.value = true       // 可以渲染权限子组件了
  // 获取客户的环境列表
  if (formData.customerID !== "") {
    // 获取客户的所有环境
    await getCustomerEnv(formData.customerID).then((Options) => {
      if (Options) {
        envOptions.value = Options || []
      }
    })

    if (envOptions.value.length === 0) {
      ElMessage({
        type: "error",
        message: "当前客户没有对应的环境信息，如需创建license，请先创建此客户的环境信息！"
      })
    } else {
      formData.envID = tempEnv
    }
  }
})
//#endregion


const form_config_item: { [key: string]: any } = reactive([
  {
    key: "customer",
    customer: [
      {
        type: "select",
        label: "客户名称",
        prop: "customerID",
        options: customerOptions,
        width: "100%",
        col: 8,
        required: true
      },
      {
        type: "select",
        label: "环境",
        prop: "envID",
        options: envOptions,
        width: "100%",
        col: 8,
        required: true
      },
      {
        type: "date",
        label: "过期日期",
        prop: "expiredDate",
        date_type: "date",
        col: 8,
        date_format: "YYYY-MM-DD",
        date_value: "YYYY-MM-DD",
        width: "1000px",
        required: true
      },
      {
        type: "select",
        label: "license版本",
        prop: "licenseVersion",
        options: [
          {label: "4.6之前", value: 1},
          {label: "4.6之后", value: 2}
        ],
        width: "100%",
        col: 8,
        required: true
      },
      {
        type: "input",
        label: "公司显示名",
        prop: "compDisplayName",
        col: 12,
        placeholder: "公司显示用名，可用中文全名（可选）eg: 白山云科技有限公司",
        width: "100%",
        max_length: 20,
        min_length: 2
      }
    ]
  },
  {
    key: "manager",
    manager: [
      {
        type: "inputNumber",
        label: "管理平台API数",
        prop: "managerApis",
        col: 8,
        required: true
      },
      {
        type: "inputNumber",
        label: "管理平台用户数",
        prop: "managerUsers",
        col: 8,
        required: true
      },
      {
        type: "inputNumber",
        label: "管理平台项目数",
        prop: "managerProjects",
        col: 8,
        required: true
      },
      {
        type: "inputNumber",
        label: "管理平台集成平台限制",
        prop: "managerIntegrations",
        col: 8,
        required: true
      },
      {
        type: "inputNumber",
        label: "管理平台支持组织数",
        prop: "managerOrganizations",
        col: 8,
        required: true
      },
      {
        type: "inputNumber",
        label: "管理平台测试限制",
        prop: "managerTests",
        col: 8,
        required: true
      },
      {
        type: "inputNumber",
        label: "管理平台发布限制",
        prop: "managerProducts",
        col: 8,
        required: true
      }
    ]
  },
  {
    key: "runtime",
    runtime: [
      {
        type: "inputNumber",
        label: "集成平台用户数",
        prop: "studioUsers",
        col: 8,
        required: true
      },
      {
        type: "input",
        label: "集成组件黑名单",
        prop: "studioCompBlackList",
        col: 14,
        placeholder: "集成平台组件黑名单（可选），通过英文逗号分隔. eg: InvokeSOAP, InvokeSAPRFC"
      },
      {
        type: "button",
        label: "一键填入企业版组件黑名单",
        col: 2,
      }
    ]
  },
  {
    key: "version",
    version: [
      {
        type: "input",
        label: "管理平台版本",
        prop: "coreApiVersion",
        col: 8,
        placeholder: "请输入版本号"
      },
      {
        type: "input",
        label: "编排平台版本",
        prop: "runtimeVersion",
        col: 8,
        placeholder: "请输入版本号"
      },
      {
        type: "input",
        label: "配置中心版本",
        prop: "cfgVersion",
        col: 8,
        placeholder: "请输入版本号"
      }
    ]
  }
])


// 合并所有的value为一个列表
const mergedValues: any[] = []
form_config_item.forEach((formItem: any) => {
  Object.keys(formItem).forEach((key) => {
    if (formItem[key] !== "key" && Array.isArray(formItem[key])) {
      formItem[key].forEach((item: any) => {
        mergedValues.push(item)
      })
    }
  })
})

const rules = reactive(InitRules(mergedValues))

const handlerSubmitForm = async (Permission: Object, CheckList: object, runtimeCheckList: object) => {
  if (formData.licenseVersion === 1) {
    Permission["version"] = formData.coreApiVersion
  } else if (formData.licenseVersion === 2) {
    Permission["coreApi"]["version"] = formData.coreApiVersion
    Permission["runtime"]["nifiVersion"] = formData.runtimeVersion
    Permission["hd-cfg-api"]["cfgVersion"] = formData.cfgVersion
  }

  formData.expiredDate = formatDateTime(formData.expiredDate)
  formData.permissionMenu = JSON.stringify(Permission)
  formData.checkList = JSON.stringify(CheckList)
  formData.runtimeCheckList = JSON.stringify(runtimeCheckList)

  await formDom.value.validate(async (valid) => {
    if (valid) {
      loading.value = true
      try {
        const res = await addCustomerLicenseApi({...formData})
        ElMessage({type: "success", message: res.msg})
        router.push({name: "licenseList"})
      } finally {
        loading.value = false
      }
    }
  })
}



/** 一键填入企业版组件黑名单 */

const studioCompBlackList = "AddLDAP,AggregateRecord,AttributeRollingWindow,CaptureChangeMySQL,CommitDatabase,CompareFuzzyHash,CompareLDAP,ConnectWebSocket,ConsumeAMQP,ConsumeAzureEventHub,ConsumeEWS,ConsumeGCPubSub,ConsumeIMAP,ConsumeJMS,ConsumeKafka,ConsumeKafka_0_10,ConsumeKafka_0_11,ConsumeKafka_1_0,ConsumeKafkaRecord_0_10,ConsumeKafkaRecord_0_11,ConsumeKafkaRecord_1_0,ConsumeMQTT,ConsumePOP3,ConsumeWindowsEventLog,ConvertAvroSchema,ConvertCSVToAvro,ConvertExcelToCSVProcessor,ConvertHL7Message,ConvertJSONToAvro,CreateHadoopSequenceFile,DeleteAzureBlobStorage,DeleteByQueryElasticsearch,DeleteDynamoDB,DeleteElasticsearch5,DeleteGCSObject,DeleteHBaseCells,DeleteHBaseRow,DeleteLDAP,DeleteMongo,DeleteRethinkDB,DeleteS3Object,DeleteSQS,EdiToJSON,EdiToXML,ExecuteFlumeSink,ExecuteFlumeSource,ExecuteInfluxDBQuery,ExecuteSparkInteractive,ExecuteStoreProcedure,ExtractAvroToAttributes,ExtractCCDAAttributes,ExtractEdiToAttributes,ExtractEmailAttachments,ExtractEmailHeaders,ExtractExcel,ExtractHL7Attributes,ExtractImageMetadata,ExtractMediaMetadata,ExtractTNEFAttachments,FetchAzureBlobStorage,FetchElasticsearch,FetchElasticsearch5,FetchElasticsearchHttp,FetchGCSObject,FetchHBaseRow,FetchS3Object,FetchVeStoreData,FetchVeStoreHistoryData,FetchVeStoreRawData,FetchVeStoreRealTimeData,FetchVeStoreSnapshotData,FilterField,FilterRecord,FuzzyHashContent,GeoEnrichIP,GetAzureEventHub,GetAzureQueueStorage,GetCouchbaseKey,GetDynamoDB,GetHBase,GetHDFS,GetHDFSEvents,GetHDFSFileInfo,GetHDFSSequenceFile,GetHTMLElement,GetIgniteCache,GetKafka,GetMongo,GetOPCDA,GetOPCData,GetOPCNodeList,GetRethinkDB,GetSAPHana,GetSNMP,GetSolr,GetSplunk,GetSQS,GetTCP,GetTwitter,HandleSAPTCPResponse,HandleSOAPHttpRequest,HandleSOAPHttpResponse,InferAvroSchema,InvokeAWSGatewayApi,InvokeDubbo,InvokeSAPRFC,InvokeSOAP,ISPEnrichIP,JsonQueryElasticsearch,ListAzureBlobStorage,ListenHL7,ListenLumberjack,ListenSAPTCP,ListenSMTP,ListenWebSocket,ListGCSBucket,ListS3,ModbusReader,ModbusSlave,ModbusWriter,ModifyDnLDAP,ModifyHTMLElement,ModifyLDAP,MoveHDFS,ParseEvtx,PublishAMQP,PublishGCPubSub,PublishJMS,PublishKafka,PublishKafka_0_10,PublishKafka_0_11,PublishKafka_1_0,PublishKafkaRecord_0_10,PublishKafkaRecord_0_11,PublishKafkaRecord_1_0,PublishMQTT,PutAzureBlobStorage,PutAzureEventHub,PutAzureQueueStorage,PutCassandraQL,PutCloudWatchMetric,PutCouchbaseKey,PutDruidRecord,PutDynamoDB,PutElasticsearch,PutElasticsearch5,PutElasticsearchHttp,PutElasticsearchHttpRecord,PutGCSObject,PutHBaseCell,PutHBaseJSON,PutHBaseRecord,PutHL7,PutHTMLElement,PutHttpVeStoreData,PutIgniteCache,PutInfluxDB,PutKafka,PutKinesisFirehose,PutKinesisStream,PutKudu,PutLambda,PutMongo,PutMongoRecord,PutRethinkDB,PutRiemann,PutS3Object,PutSAPHana,PutSlack,PutSNS,PutSolrContentStream,PutSolrRecord,PutSplunk,PutSQS,PutVeStoreData,PutWebSocket,QueryCassandra,QueryDNS,QueryElasticsearchHttp,QuerySolr,QueryWhois,ResizeImage,RollbackDatabase,RouteHL7,RunMongoAggregation,ScanHBase,ScrollElasticsearchHttp,SearchLDAP,SendSAPIDOC,SetSNMP,SortRecord,SplitEdi,StoreInKiteDataset"
const setStudioCompBlackList = () => {
  formData.studioCompBlackList= studioCompBlackList
}
</script>

<style lang="scss" scoped>
.tooltip-base-box {
  width: 600px;
}

.tooltip-base-box .row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.tooltip-base-box .center {
  justify-content: center;
}

.tooltip-base-box .box-item {
  width: 110px;
  margin-top: 10px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.text {
  font-size: 14px;
}

.item {
  margin-bottom: 18px;
}

.box-card {
  width: 480px;
}

.box-row {
  margin-left: 5%;
  margin-right: 5%;
}
</style>
